package com.kuangstudy.controller.redisson;

import lombok.extern.slf4j.Slf4j;
import org.redisson.RedissonRedLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2021/6/9 12:56
 */
@RestController
@Slf4j
public class RedLockRedissonController {

    @Autowired
    private RedissonClient redissonClient1;
    @Autowired
    private RedissonClient redissonClient2;
    @Autowired
    private RedissonClient redissonClient3;

    @GetMapping("/redlock")
    public void get(String key) throws InterruptedException {
        // 准备三个锁，mylock是就是分布式锁的key
        RLock rLock1 = redissonClient1.getLock(key);
        RLock rLock2 = redissonClient2.getLock(key);
        RLock rLock3 = redissonClient3.getLock(key);
        //1：创建一个红锁
        RedissonRedLock redissonRedLock = new RedissonRedLock(rLock1, rLock2, rLock3);
        boolean islock;
        try {
            // waittime：是锁的等待时间处理，正常情况下是：5s
            // leaseTime：是租约时间，就是redis的key的正常过期
            islock = redissonRedLock.tryLock(1000 * 3, 1000 * 5, TimeUnit.MILLISECONDS);
            log.info("1----线程：{}，是否拿到锁：{}", Thread.currentThread().getName(), islock);
            if (islock) {
                log.info("2----线程：{}，获取锁成功！", Thread.currentThread().getName());
                //模拟业务执行超时30分钟
                Thread.sleep(3000);
            }
        } catch (Exception ex) {
            log.error("get lock is error");
        } finally {
            // 无论如何都要释放锁
            log.info("3-----线程：{}，释放锁成功！", Thread.currentThread().getName());
            redissonRedLock.unlock();
        }

    }
}
